package com.yinhe.music.yhmusic.downmusic;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.NotificationCompat;
import android.widget.RemoteViews;
import android.widget.Toast;

import com.hwangjr.rxbus.RxBus;
import com.yinhe.music.common.utils.HttpUtil;
import com.yinhe.music.common.utils.ScanMusicUtil;
import com.yinhe.music.event.RxBusEventType;
import com.yinhe.music.yhmusic.R;
import com.yinhe.music.yhmusic.cache.CacheManager;
import com.yinhe.music.yhmusic.constants.BasicConfig;
import com.yinhe.music.yhmusic.db.DataBaseAccessor;
import com.yinhe.music.yhmusic.db.bean.DownloadMusicEntity;
import com.yinhe.music.yhmusic.log.MLog;
import com.yinhe.music.yhmusic.model.Music;
import com.yinhe.music.yhmusic.utils.CommonUtils;
import com.yinhe.music.yhmusic.utils.ToastUtils;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by wm on 2016/12/13.
 */
public class DownloadManager implements IDownloadManager {

    private boolean d = true;
    private static final String TAG = "DownloadManager";
    private ExecutorService executorService;
    /**
     * 即将要准备下载列表
     */
    private ArrayList<Long> prepareTaskList = new ArrayList<>();

    /**
     * 下载列表
     */
    private ArrayList<DownloadMusicEntity> mDownloadingMusicTaskList = new ArrayList<>();


    private int downTaskDownloaded = -1;
    private DownloadTask currentTask;
    private NotificationManager mNotificationManager;
    private Service mContext;
    private int notificationid = 10;
    private boolean isForeground;
    private RemoteViews remoteViews;

    private Handler mHandler = new Handler(Looper.getMainLooper());

    public DownloadManager(Service service) {
        mContext = service;
        mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        // 【适配Android8.0】给NotificationManager对象设置NotificationChannel
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel("notification_id", "notification_name", NotificationManager.IMPORTANCE_LOW);
            mNotificationManager.createNotificationChannel(channel);
        }
        executorService = Executors.newSingleThreadExecutor();

        List<DownloadMusicEntity> list = DataBaseAccessor.getInstance().getDowningMusic();
        if (list != null) {
            mDownloadingMusicTaskList.addAll(list);
//            for (DownloadMusicEntity entity : list) {
//                prepareTaskList.add(entity.getDownloadId());
//            }
        }
    }

    private DownloadTaskListener mListener = new DownloadTaskListener() {
        @Override
        public void onPrepare(final DownloadTask downloadTask) {
//            MLog.info( TAG, TAG + " task onPrepare");
//            mHandler.post(new Runnable() {
//                @Override
//                public void run() {
//                    for (DownloadTaskListener listener : mListeners) {
//                        listener.onPrepare(downloadTask);
//                    }
//                }
//            });

        }

        @Override
        public void onStart(final DownloadTask downloadTask) {
            updateDownloadMusicEntityDownloadStatus(downloadTask.getDbEntity());
            RxBus.get().post(RxBusEventType.Download.DOWNLOAD_START, downloadTask);
        }

        @Override
        public void onDownloading(final DownloadTask downloadTask) {
            updateDownloadMusicEntityDownloadStatus(downloadTask.getDbEntity());
            RxBus.get().post(RxBusEventType.Download.DOWNLOAD_PROCESS, downloadTask);
        }

        @Override
        public void onPause(final DownloadTask downloadTask) {
            RxBus.get().post(RxBusEventType.Download.DOWNLOAD_PAUSE, downloadTask);
        }

        @Override
        public void onCancel(final DownloadTask downloadTask) {
            RxBus.get().post(RxBusEventType.Download.DOWNLOAD_CANCEL, downloadTask);
        }

        @Override
        public void onCompleted(final DownloadTask downloadTask) {
            updateDownloadMusicEntityDownloadStatus(downloadTask.getDbEntity());
            removeDownloadTask(downloadTask.getId());
            DataBaseAccessor.getInstance().updateDownMusic(downloadTask.getDbEntity());

            prepareTaskList.remove(currentTask.getId());
            currentTask.mListener = null;
            currentTask = null;
            downTaskDownloaded++;

            File file = new File(BasicConfig.getInstance().getMusicDownLoadDir() +
                    File.separator + downloadTask.getFileName());

            new ScanMusicUtil(mContext, file, () -> {
                List<Music> musicList = CacheManager.getInstance().getScanMusic();
                DownloadMusicEntity musicEntity = downloadTask.getDbEntity();
                musicList.add(new Music(musicEntity));
                CacheManager.getInstance().setScanMusic(musicList);
            });

            mHandler.post(() -> {
                RxBus.get().post(RxBusEventType.Download.DOWNLOAD_COMPLETE, downloadTask);
                startTask();
            });

        }

        @Override
        public void onError(final DownloadTask downloadTask, final int errorCode) {
            updateDownloadMusicEntityDownloadStatus(downloadTask.getDbEntity());

            prepareTaskList.remove(downloadTask.getId());
            currentTask.mListener = null;
            currentTask = null;

            mHandler.post(() -> {
                RxBus.get().post(RxBusEventType.Download.DOWNLOAD_ERROR, downloadTask);
                startTask();
            });
        }
    };

    public ArrayList<Long> getPrepareTasks() {
        return prepareTaskList;
    }

    public void onDestroy() {
        mNotificationManager.cancel(notificationid);
    }

    public DownloadMusicEntity getCurrentTask() {
        if (currentTask != null) {
            return currentTask.getDbEntity();
        }
        return null;
    }

    public ArrayList<Long> getPrepareTaskList() {
        return prepareTaskList;
    }

    public ArrayList<DownloadMusicEntity> getDownloadingMusicTaskList() {
        return mDownloadingMusicTaskList;
    }

    private String getDownSave() {
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            File file = BasicConfig.getInstance().getMusicDownLoadDir();
            if (!file.mkdirs()) {
                Toast.makeText(mContext, "储存卡无法创建文件", Toast.LENGTH_SHORT).show();
                return null;
            }
            return file.getAbsolutePath();
        } else {
            Toast.makeText(mContext, "没有储存卡", Toast.LENGTH_SHORT).show();
            return null;
        }
    }


    private void upDateNotification() {
        if (currentTask == null) {
            return;
        }
        if (!isForeground) {
            mContext.startForeground(notificationid, getNotification(false));
            isForeground = true;
        } else {
            mNotificationManager.notify(notificationid, getNotification(false));
        }
    }

    private void cancleNotification() {
        mContext.stopForeground(true);
        isForeground = false;
        mNotificationManager.notify(notificationid, getNotification(true));
        downTaskDownloaded = -1;
    }

    private DownloadMusicEntity getDownloadMusicEntityById(long id) {
        for (DownloadMusicEntity entity : mDownloadingMusicTaskList) {
            if (entity.getDownloadId() == id) {
                return entity;
            }
        }
        return null;
    }

    private void updateDownloadMusicEntityDownloadStatus(DownloadMusicEntity downloadMusicEntity) {
        for (DownloadMusicEntity entity : mDownloadingMusicTaskList) {
            if (entity.getDownloadId() == downloadMusicEntity.getDownloadId()) {
                entity.setDownloadStatus(downloadMusicEntity.getDownloadStatus());
                break;
            }
        }
    }

    private void removeDownloadTask(long id) {
        for (DownloadMusicEntity entity : mDownloadingMusicTaskList) {
            if (entity.getDownloadId() == id) {
                mDownloadingMusicTaskList.remove(entity);
                break;
            }
        }
    }

    public void startTask() {
        if (currentTask != null) {
            return;
        }
        if (prepareTaskList.size() > 0) {
            DownloadTask downloadTask;
            long downloadId = prepareTaskList.get(0);

            DownloadMusicEntity entity = getDownloadMusicEntityById(downloadId);

            if (entity == null) {
                prepareTaskList.remove(0);
                return;
            }

            entity.setCompletedSize(0L);
            entity.setToolSize(0L);
            downloadTask = new DownloadTask(mContext, mListener);
            downloadTask.setDBEntity(entity);

            if (downloadTask.getDownloadStatus() != DownloadStatus.DOWNLOAD_STATUS_COMPLETED) {
                downloadTask.setDownloadStatus(DownloadStatus.DOWNLOAD_STATUS_PREPARE);
                downloadTask.setHttpClient(HttpUtil.mOkHttpClient);
                executorService.submit(downloadTask);
                currentTask = downloadTask;
                upDateNotification();
            } else {
                prepareTaskList.remove(0);
                startTask();
            }
        } else {
            MLog.info(TAG, " no task");
            cancleNotification();
        }
    }


    public void cancel(long taskId) {
        List<Integer> taskIdList = new ArrayList<>();
        if (prepareTaskList.contains(taskId)) {
            prepareTaskList.remove(taskId);
        }

        removeDownloadTask(taskId);
        taskIdList.add((int) taskId);
        DataBaseAccessor.getInstance().deleteDownMusicByList(taskIdList, false);
        upDateNotification();

        if (currentTask != null) {
            if (taskId == currentTask.getId()) {
                currentTask.cancel();
                currentTask.setDownloadStatus(DownloadStatus.DOWNLOAD_STATUS_CANCEL);
                currentTask.mListener = null;
                currentTask = null;
                startTask();
            }

            if (prepareTaskList.size() == 0 && currentTask != null) {
                currentTask.mListener = null;
                currentTask = null;
            }
        }
    }

    public void pause(long taskid) {
        prepareTaskList.remove(taskid);
        if (currentTask != null && taskid == currentTask.getId()) {
            currentTask.pause();
            RxBus.get().post(RxBusEventType.Download.DOWNLOAD_PAUSE, currentTask);
            currentTask.mListener = null;
            currentTask = null;
        }

        if (prepareTaskList.size() == 0 && currentTask != null) {
            RxBus.get().post(RxBusEventType.Download.DOWNLOAD_PAUSE, currentTask);
            currentTask.mListener = null;
            currentTask = null;
        } else {
            startTask();
        }
        upDateNotification();
    }

    private Notification getNotification(boolean complete) {
        if (downTaskDownloaded == -1) {
            downTaskDownloaded = 0;
        }
        remoteViews = new RemoteViews(mContext.getPackageName(), R.layout.down_notification);

        final Intent nowPlayingIntent = new Intent();
        nowPlayingIntent.setComponent(new ComponentName("com.yinhe.music.yhmusic", "com.yinhe.music.yhmusic.activity.DownActivity"));
        PendingIntent clickIntent = PendingIntent.getBroadcast(mContext, 0, nowPlayingIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setImageViewResource(R.id.image, R.drawable.placeholder_disk_210);
        if (complete) {
            remoteViews.setTextViewText(R.id.title, "雪域音乐");
            remoteViews.setTextViewText(R.id.text, "下载完成，点击查看");
            remoteViews.setTextViewText(R.id.time, showDate());
        } else {
            DownloadTask task = currentTask;
            if (task != null) {
                remoteViews.setTextViewText(R.id.title, "下载进度：" + downTaskDownloaded + "/" + prepareTaskList.size());
                remoteViews.setTextViewText(R.id.text, "正在下载：" + task.getFileName());
                remoteViews.setTextViewText(R.id.time, showDate());
            } else {
                remoteViews.setTextViewText(R.id.title, "雪域音乐");
                remoteViews.setTextViewText(R.id.text, "下载出错，请重试");
                remoteViews.setTextViewText(R.id.time, showDate());
            }
        }

        NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext).setContent(remoteViews)
                .setSmallIcon(R.drawable.ic_notification)
                .setContentIntent(clickIntent);
        // 【适配Android8.0】设置Notification的Channel_ID,否则不能正常显示
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder.setChannelId("notification_id");
        }
        if (CommonUtils.isJellyBeanMR1()) {
            builder.setShowWhen(false);
        }
        return builder.build();
    }

    public static String showDate() {
        SimpleDateFormat sDateFormat = new SimpleDateFormat("a hh:mm");
        return sDateFormat.format(new Date());
    }


    @Override
    public void addDownloadTask(Music music) {
        if (music != null) {

            DownloadMusicEntity dbEntity = new DownloadMusicEntity(music, DownloadStatus.DOWNLOAD_STATUS_INIT);
            DataBaseAccessor.getInstance().insertDownMusicSyn(dbEntity);

            mDownloadingMusicTaskList.add(dbEntity);
            prepareTaskList.add(dbEntity.getDownloadId());

            upDateNotification();

            if (currentTask != null) {
                return;
            }
            startTask();
            ToastUtils.show(R.string.down_music);
        }
    }

    @Override
    public void resumeStartDownloadTask(long taskId) {
        prepareTaskList.add(taskId);
        startTask();
    }

    @Override
    public void pauseDownloadTask(long taskId) {
        pause(taskId);
    }

    @Override
    public void cancelDownloadTask(long taskId) {
        cancel(taskId);
    }

    @Override
    public void startAllDownloadTask() {
        prepareTaskList.clear();
        if (currentTask != null) {
            currentTask.setDownloadStatus(DownloadStatus.DOWNLOAD_STATUS_CANCEL);
            currentTask.mListener = null;
            currentTask = null;
        }

        for (DownloadMusicEntity entity : mDownloadingMusicTaskList) {
            prepareTaskList.add(entity.getDownloadId());
        }
        startTask();
    }

    @Override
    public void pauseAllDownloadTask() {
        if (currentTask != null) {
            currentTask.pause();
            RxBus.get().post(RxBusEventType.Download.DOWNLOAD_PAUSE, currentTask);
            currentTask.mListener = null;
            currentTask = null;
        }
        prepareTaskList.clear();
        cancleNotification();
    }
}
